<!DOCTYPE html>
<html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-0 vector-toc-not-available vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-0 skin-theme-clientpref-day vector-sticky-header-enabled" lang="de" dir="ltr"><head>
<meta charset="UTF-8">
<title>Generische Programmierung in Java</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./_res_/favicon.png">
<link rel="canonical" href="https://de.wikipedia.org/wiki/Generische_Programmierung_in_Java"> <link href="./_mw_/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.wikimediamessages.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link href="./_mw_/ext.gadget.citeRef.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.defaultPlainlinks.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonHide.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonLayout.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonStyle.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiDarkmode.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiResponsive.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.specialSearch.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="./_mw_/site.styles.css">
<link rel="stylesheet" type="text/css" href="./_mw_/noscript.css">
<link rel="stylesheet" type="text/css" href="./_res_/footer.css">
<link rel="stylesheet" type="text/css" href="./_res_/vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Generische_Programmierung_in_Java rootpage-Generische_Programmierung_in_Java skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-main">Generische Programmierung in Java</span></h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="contentSub">
<div id="mw-content-subtitle"></div>
</div>
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="de" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="de" dir="ltr"><p><b><a href="Generische_Programmierung" title="Generische Programmierung">Generische Programmierung</a> in <a href="Java_(Programmiersprache)" title="Java (Programmiersprache)">Java</a></b> wird durch sog. <i>Generics</i> seit Java 1.5 ermöglicht. Der Begriff steht synonym für „parametrisierte Typen“. Die Idee dahinter ist, zusätzliche <a href="Variable_(Programmierung)" title="Variable (Programmierung)">Variablen</a> für <a href="Datentyp" title="Datentyp">Datentypen</a> einzuführen. Diese <i>Typ-Variablen</i> repräsentieren zum Zeitpunkt der Implementierung unbekannte Typen. Erst bei der Verwendung der <a href="Klasse_(objektorientierte_Programmierung)" class="mw-redirect" title="Klasse (objektorientierte Programmierung)">Klassen</a>, <a href="Schnittstelle_(Objektorientierung)" title="Schnittstelle (Objektorientierung)">Schnittstellen</a> und <a href="Methode_(Programmierung)" title="Methode (Programmierung)">Methoden</a> werden diese Typ-Variablen durch konkrete Typen ersetzt. Damit kann <a href="Typsicherheit" title="Typsicherheit">typsichere</a> Programmierung meistens gewährleistet werden. Jedoch nicht immer.<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Das_Konzept">Das Konzept</h2></div>
<p>Ab Version 5.0 („Tiger“, 2004 veröffentlicht) steht auch in der Programmiersprache Java mit den Generics ein <a href="Syntax" title="Syntax">syntaktisches</a> Mittel für die generische Programmierung zur Verfügung. Damit lassen sich Klassen und Methoden (Methoden auch unabhängig von ihren Klassen) mit <i>Typen</i> parametrisieren.
Damit werden der Sprache einige ähnliche Möglichkeiten eröffnet, die sich vergleichbar bei den <a href="Template_(Programmierung)" class="mw-redirect" title="Template (Programmierung)">Templates</a> in <a href="C%2B%2B" title="C++">C++</a> bieten.
</p><p>Prinzipiell gibt es aber durchaus wesentliche Unterschiede. Während in Java über die <i>Schnittstelle</i> der Typparameter parametrisiert wird, wird in C++ direkt über den <i>Typ</i> des Typparameters selbst parametrisiert. Der <a href="Quelltext" title="Quelltext">Quelltext</a> eines C++-Templates muss für den Anwender (d. h. beim Einsetzen des Typparameters) verfügbar sein, während ein <a href="Generischer_Typ" title="Generischer Typ">generischer Java-Typ</a> auch als übersetzter <a href="Bytecode" title="Bytecode">Bytecode</a> veröffentlicht werden kann. Für verschiedene konkret verwendete Typparameter produziert der <a href="Compiler" title="Compiler">Compiler</a> duplizierten Zielcode.
</p><p>Beispielsweise bietet die Funktion <code>std::sort</code> in C++ die Möglichkeit, alle <a href="Container_(Informatik)" title="Container (Informatik)">Container</a> zu sortieren, die bestimmte Methoden anbieten (hier speziell <code>begin()</code> und <code>end()</code>, die jeweils einen <a href="Iterator" title="Iterator">Iterator</a> liefern) und deren Typparameter den <code>operator<</code> implementiert (oder explizit eine andere Vergleichsfunktion angegeben wurde). Ein Nachteil, der sich durch dieses System ergibt, ist die (für den Programmierer!) schwierigere Übersetzung. Der Compiler hat keine andere Möglichkeit, als den Typparameter in jedem Fall durch den geforderten konkreten Typ zu ersetzen und den ganzen Code erneut zu kompilieren.
</p><p>Sehr leicht können bei unpassenden Typparametern und anderen Problemen komplizierte und unverständliche Compiler-Meldungen entstehen, was einfach mit der Tatsache zusammenhängt, dass die konkreten Anforderungen an die Typparameter unbekannt sind. Die Arbeit mit C++-Templates erfordert deshalb eine lückenlose Dokumentation der Anforderungen an einen Typparameter. Durch Template-<a href="Metaprogrammierung" title="Metaprogrammierung">Metaprogrammierung</a> können die meisten Anforderungen (<a href="Basisklasse" title="Basisklasse">Basisklasse</a>, Vorhandensein von Methoden, Kopierbarkeit, Zuweisbarkeit etc.) auch in speziellen Konstrukten abgefragt werden, wodurch sich lesbarere Fehlermeldungen ergeben. Obgleich sie standardkonform sind, werden diese Konstrukte jedoch nicht von allen Compilern unterstützt.
</p><p>Dagegen sind den generischen Klassen und Methoden in Java die Anforderungen (<span style="font-style:normal;font-weight:normal"><a href="Englische_Sprache" title="Englische Sprache">englisch</a></span> <span lang="en-Latn" style="font-style:italic">constraints</span>) an ihre eigenen Typparameter bekannt. Um eine Collection (ohne Comparator) zu sortieren, müssen die enthaltenen Elemente vom Typ Comparable sein, also dieses Interface implementiert haben. Der Compiler muss lediglich prüfen, ob der Typparameter ein Untertyp von Comparable ist, und kann damit schon sicherstellen, dass der Code korrekt ist (d. h. die erforderliche Methode compareTo verfügbar ist). Weiterhin wird ein und derselbe Code für alle konkreten Typen verwendet und nicht jedes Mal dupliziert.
</p>
<div class="mw-heading mw-heading2"><h2 id="Praktische_Beispiele">Praktische Beispiele</h2></div>
<p>Ein Programm verwendet eine <code>ArrayList</code>, um eine <a href="Liste_(Datenstruktur)" title="Liste (Datenstruktur)">Liste</a> von <code>JButton</code>s zu speichern.
</p><p>Bisher war die <code>ArrayList</code> auf den Typ <code>Object</code> fixiert:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="p">();</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 1"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 2"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 3"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 4"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 5"</span><span class="p">));</span>
<span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">size</span><span class="p">();</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">JButton</span><span class="w"> </span><span class="n">button</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">JButton</span><span class="p">)</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
<span class="w"> </span><span class="n">button</span><span class="p">.</span><span class="na">setBackground</span><span class="p">(</span><span class="n">Color</span><span class="p">.</span><span class="na">white</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Man beachte die notwendige <a href="Typumwandlung" title="Typumwandlung">explizite Typumwandlung</a> (auch „Cast“ genannt) sowie die Typunsicherheit, die damit verbunden ist. Man könnte versehentlich ein <a href="Objekt_(Programmierung)" title="Objekt (Programmierung)">Objekt</a> in der <code>ArrayList</code> speichern, das keine Instanz der Klasse <code>JButton</code> ist. Die Information über den genauen Typ geht beim Einfügen in die Liste verloren, der Compiler kann also nicht verhindern, dass zur <a href="Laufzeit_(Informatik)" title="Laufzeit (Informatik)">Laufzeit</a> bei der expliziten Typumwandlung von <code>JButton</code> eine <code>ClassCastException</code> auftritt.
</p><p>Mit <i>generischen Typen</i> ist in Java Folgendes möglich:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><</span><span class="n">JButton</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">JButton</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 1"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 2"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 3"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 4"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 5"</span><span class="p">));</span>
<span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">size</span><span class="p">();</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="na">setBackground</span><span class="p">(</span><span class="n">Color</span><span class="p">.</span><span class="na">white</span><span class="p">);</span>
</pre></div>
<p>Beim Auslesen ist nun keine explizite Typumwandlung mehr notwendig, beim Speichern ist es nur noch möglich, JButtons in der <code>ArrayList</code> <i>list</i> abzulegen.
</p><p>Ab Java7 ist die Instanzierung generischer Typen vereinfacht worden. Die erste Zeile in obigem Beispiel kann seit Java 7 folgendermaßen geschrieben werden:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><</span><span class="n">JButton</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><></span><span class="p">();</span>
</pre></div>
<p>Die beiden leeren spitzen Klammern werden aufgrund ihrer Form auch als <i>Diamant-Operator</i> (<span style="font-style:normal;font-weight:normal"><a href="Englische_Sprache" title="Englische Sprache">englisch</a></span> <span lang="en-Latn" style="font-style:italic">Diamond-Operator</span>) bezeichnet.<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup>
</p><p>Durch Kombination von generischen Typen mit den erweiterten For-Schleifen lässt sich obiges Beispiel kürzer fassen:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><</span><span class="n">JButton</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><></span><span class="p">();</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 1"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 2"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 3"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 4"</span><span class="p">));</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Button 5"</span><span class="p">));</span>
<span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">JButton</span><span class="w"> </span><span class="n">b</span><span class="p">:</span><span class="w"> </span><span class="n">list</span><span class="p">)</span>
<span class="w"> </span><span class="n">b</span><span class="p">.</span><span class="na">setBackground</span><span class="p">(</span><span class="n">Color</span><span class="p">.</span><span class="na">white</span><span class="p">);</span>
</pre></div>
<p>Ein Beispiel für eine generische Klasse, die zwei Objekte von beliebigem, aber einander gleichem Typ beinhaltet, liefert der folgende Beispielcode:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">DoubleObject</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">private</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="n">object1</span><span class="p">;</span>
<span class="w"> </span><span class="kd">private</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="n">object2</span><span class="p">;</span>
<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="nf">DoubleObject</span><span class="p">(</span><span class="n">T</span><span class="w"> </span><span class="n">object1</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="n">object2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">object1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">object1</span><span class="p">;</span>
<span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">object2</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">toString</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">object1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">", "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">object2</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">DoubleObject</span><span class="o"><</span><span class="n">String</span><span class="o">></span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">DoubleObject</span><span class="o"><></span><span class="p">(</span><span class="s">"abc"</span><span class="p">,</span><span class="w"> </span><span class="s">"def"</span><span class="p">);</span>
<span class="w"> </span><span class="n">DoubleObject</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">DoubleObject</span><span class="o"><></span><span class="p">(</span><span class="mi">123</span><span class="p">,</span><span class="w"> </span><span class="mi">456</span><span class="p">);</span>
<span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"DoubleObject<String> s="</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span>
<span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"DoubleObject<Integer> i="</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">i</span><span class="p">.</span><span class="na">toString</span><span class="p">());</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Varianzfälle"><span id="Varianzf.C3.A4lle"></span>Varianzfälle</h2></div>
<p>In Java können die nachfolgenden Varianzfälle unterschieden werden. Sie bieten jeweils eine völlig eigenständige Flexibilität beim Umgang mit generischen Typen und sind jeweils absolut statisch typsicher.
</p>
<div class="mw-heading mw-heading3"><h3 id="Invarianz">Invarianz</h3></div>
<p>Bei Invarianz ist der Typparameter eindeutig. Damit bietet Invarianz die größtmögliche Freiheit bei der Benutzung des Typparameters. Beispielsweise sind für die Elemente einer <code>ArrayList<Integer></code> alle Aktionen erlaubt, die auch bei der direkten Benutzung eines einzelnen Integers erlaubt sind (inklusive <a href="Autoboxing" class="mw-redirect" title="Autoboxing">Autoboxing</a>). Beispiel:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="n">Integer</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
<span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">).</span><span class="na">methodeVonInteger</span><span class="p">();</span>
<span class="n">list</span><span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="n">index</span><span class="p">,</span><span class="w"> </span><span class="mi">98347</span><span class="p">);</span><span class="w"> </span><span class="c1">// Autoboxing, entspricht Integer.valueOf(98347)</span>
<span class="kt">int</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span><span class="w"> </span><span class="c1">// Auto-Unboxing</span>
</pre></div>
<p>Diese Möglichkeiten werden mit wenig Flexibilität bei der <a href="Zuweisung" title="Zuweisung">Zuweisung</a> von Objekten der generischen Klasse selbst erkauft. Beispielsweise ist Folgendes nicht erlaubt:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><</span><span class="n">Number</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="p">();</span>
</pre></div>
<p>und das, obwohl Integer von Number abgeleitet ist. Der Grund liegt darin, dass der Compiler hier nicht mehr sicherstellen kann, dass keine Typfehler auftreten. Mit <a href="Array_(Datentyp)" title="Array (Datentyp)">Arrays</a>, die eine solche Zuweisung erlauben, hat man schlechte Erfahrungen gemacht:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="c1">// OK, Integer[] ist abgeleitet von Number[]</span>
<span class="n">Number</span><span class="o">[]</span><span class="w"> </span><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Integer</span><span class="o">[</span><span class="mi">10</span><span class="o">]</span><span class="p">;</span>
<span class="c1">// ArrayStoreException zur Laufzeit: Double -> Integer sind nicht</span>
<span class="c1">// zuweisungskompatibel</span>
<span class="n">array</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Double</span><span class="p">(</span><span class="mf">5.0</span><span class="p">);</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Kovarianz">Kovarianz</h3></div>
<p>Man bezeichnet Arrays als <a href="Kovarianz_und_Kontravarianz" title="Kovarianz und Kontravarianz">kovariant</a>, was besagt:
</p>
<div>Aus <b>T extends V</b> folgt: <b>T[] extends V[]</b></div>
<p>oder allgemeiner:
</p>
<div>Aus <b>T extends V</b> folgt: <b>GenerischerTyp<T> extends GenerischerTyp<V></b></div>
<p>Es verhält sich also der Array-Typ bzgl. der <a href="Vererbung_(Programmierung)" title="Vererbung (Programmierung)">Vererbungshierarchie</a> genauso wie der Typparameter.
Kovarianz ist auch mit generischen Typen möglich, allerdings nur mit Einschränkungen, so dass Typfehler zur <a href="%C3%9Cbersetzungszeit" title="Übersetzungszeit">Kompilierzeit</a> ausgeschlossen werden können.
</p><p>Referenzen müssen mit der Syntax <b>? extends T</b> explizit als kovariant gekennzeichnet werden. T heißt <i>upper typebound</i>, also der allgemeinste Typparameter, der erlaubt ist.
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><?</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Number</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="p">;</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Double</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Long</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="p">();</span>
<span class="c1">// Typfehler vom Compiler</span>
<span class="n">list</span><span class="p">.</span><span class="na">set</span><span class="p">(</span><span class="n">index</span><span class="p">,</span><span class="w"> </span><span class="n">myInteger</span><span class="p">);</span>
<span class="c1">// OK aber Warnung vom Compiler: unchecked cast</span>
<span class="p">((</span><span class="n">List</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="p">)</span><span class="w"> </span><span class="n">list</span><span class="p">).</span><span class="na">set</span><span class="p">(</span><span class="n">index</span><span class="p">,</span><span class="w"> </span><span class="n">myInteger</span><span class="p">);</span>
</pre></div>
<p>Das Ablegen von Elementen in diesen Listen ist nicht möglich, da dies, wie oben beschrieben, nicht typsicher ist (Ausnahme: <code><a href="Nullwert" title="Nullwert">null</a></code> kann abgelegt werden). Bereits zur Kompilierzeit tritt ein Fehler auf. Allgemeiner gesagt, ist die Zuweisung
</p>
<div><b>?</b> → <b>? extends T</b></div>
<p>nicht erlaubt.
</p><p>Möglich dagegen ist das Auslesen von Elementen:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">Number</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span><span class="w"> </span><span class="c1">// OK</span>
<span class="n">Integer</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span><span class="w"> </span><span class="c1">// Typfehler: Es muss sich bei '? extends Number'</span>
<span class="w"> </span><span class="c1">// nicht um ein Integer handeln.</span>
<span class="n">Integer</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">Integer</span><span class="p">)</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span><span class="w"> </span><span class="c1">// OK</span>
</pre></div>
<p>Die Zuweisung
</p>
<div><b>? extends T</b> → <b>T (oder Basisklasse)</b></div>
<p>ist also erlaubt, nicht aber die Zuweisung
</p>
<div><b>? extends T</b> → <b>abgeleitet von T</b></div>
<p>Generics bieten also wie Arrays kovariantes Verhalten, verbieten aber alle Operationen, die typunsicher sind.
</p>
<div class="mw-heading mw-heading3"><h3 id="Kontravarianz">Kontravarianz</h3></div>
<p>Kontravarianz bezeichnet das Verhalten der Vererbungshierarchie des generischen Typs entgegen der Hierarchie seines Typparameters. Übertragen auf das obige Beispiel würde das bedeuten: Eine Liste<Number> wäre zuweisungskompatibel zu einer Liste<Double>.
Dies wird folgendermaßen bewerkstelligt:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><?</span><span class="w"> </span><span class="kd">super</span><span class="w"> </span><span class="n">Double</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="p">;</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Number</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Double</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Object</span><span class="o">></span><span class="p">();</span>
</pre></div>
<p>Ein Objekt, das sich kontravariant verhält, darf keine Annahmen darüber machen, inwiefern ein Element vom Typ V von T abgeleitet ist, wobei T der <i>lower Typebound</i> ist (im Beispiel von <code style="white-space: nowrap">? super Double</code> ist T <code>Double</code>).
Deshalb kann aus den obigen Listen nicht gelesen werden:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="c1">// Fehler: 'list' könnte vom Typ List<Object> sein</span>
<span class="n">Number</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
<span class="c1">// Fehler: 'list' könnte List<Object> oder List<Number> sein</span>
<span class="n">Double</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
<span class="c1">// Die einzige Ausnahme: Objects sind auf jeden Fall in der Liste</span>
<span class="n">Object</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
</pre></div>
<p>Nicht erlaubt, da nicht typsicher, ist also die Zuweisung <b>? super T → (abgeleitet von Object)</b>
</p><p>Unschwer zu erraten: Im Gegenzug kann in eine solche Liste ein Element abgelegt werden:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><?</span><span class="w"> </span><span class="kd">super</span><span class="w"> </span><span class="n">Number</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="p">;</span>
<span class="n">list</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">Double</span><span class="p">(</span><span class="mf">3.0</span><span class="p">));</span><span class="w"> </span><span class="c1">// OK: 'list' hat immer den Typ List<Number></span>
<span class="w"> </span><span class="c1">// oder List<Basisklasse von Number>. Damit</span>
<span class="w"> </span><span class="c1">// ist die Zuweisung Double -> T immer erlaubt.</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Uneingeschränkte_parametrische_Polymorphie"><span id="Uneingeschr.C3.A4nkte_parametrische_Polymorphie"></span>Uneingeschränkte parametrische Polymorphie</h3></div>
<p>Zu guter Letzt bieten Generics noch gänzlich polymorphes Verhalten an. Hierbei kann keinerlei Aussage über die Typparameter gemacht werden, denn es wird in beide Richtungen keine Grenze angegeben. Dafür wurde die <a href="Wildcard_(Java)" title="Wildcard (Java)">Wildcard</a> definiert. Sie wird durch ein Fragezeichen repräsentiert.
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="n">List</span><span class="o"><?></span><span class="w"> </span><span class="n">list</span><span class="p">;</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Integer</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">Object</span><span class="o">></span><span class="p">();</span>
<span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o"><</span><span class="n">String</span><span class="o">></span><span class="p">();</span>
<span class="c1">// ...</span>
</pre></div>
<p>Der Typparameter selbst kann hierbei nicht genutzt werden, da keine Aussage möglich ist. Lediglich die Zuweisung T → Object ist erlaubt, da T auf jeden Fall ein Object ist. Im Gegenzug ist garantiert, dass der Code mit <i>allen</i> Ts arbeiten kann.
</p><p>Nützlich kann so etwas sein, wenn man nur mit dem generischen Typ arbeitet:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="c1">// Keine Informationen über den Typparameter nötig, kann ''beliebige'' Listen</span>
<span class="c1">// aufnehmen.</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">readSize</span><span class="p">(</span><span class="n">List</span><span class="o"><?></span><span class="w"> </span><span class="n">list</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">size</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<p>Zur Verdeutlichung, dass hier Wildcards unnötig sind, und es eigentlich gar nicht um irgendeine Varianz geht, sei folgende Implementierung der obigen Funktion angegeben:
</p>
<div class="mw-highlight mw-highlight-lang-java mw-content-ltr" dir="ltr"><pre><span></span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">readSize</span><span class="p">(</span><span class="n">List</span><span class="o"><</span><span class="n">T</span><span class="o">></span><span class="w"> </span><span class="n">list</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">list</span><span class="p">.</span><span class="na">size</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Weblinks">Weblinks</h2></div>
<ul><li>Ina Brenner: <a rel="nofollow" class="external text" href="https://www.theserverside.de/java-generics-generische-methoden-klassen-und-interfaces/">Tutorial zu Generics in Java</a> von der Autorin eines Buchs zur Java-Zertifizierung SCJP</li>
<li>Klaus Kreft, Angelika Langer: <a rel="nofollow" class="external text" href="https://angelikalanger.com/Articles/Topics.html#JavaGenerics/">Artikelserie zu Generics in Java</a> im JavaSpektrum</li>
<li><a href="Christian_Ullenboom" title="Christian Ullenboom">Christian Ullenboom</a>: <a rel="nofollow" class="external text" href="https://openbook.rheinwerk-verlag.de/javainsel/12_001.html">Kapitel zu Generischen Datentypen</a> aus dem Galileo-Openbook <i>Java ist auch eine Insel</i></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Einzelnachweise">Einzelnachweise</h2></div>
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text">Nada Amin, Ross Tate: <cite class="lang" lang="en" dir="auto" style="font-style:italic">Java and Scala’s Type Systems are Unsound: The Existential Crisis of Null Pointers</cite>. In: ACM (Hrsg.): <cite class="lang" lang="en" dir="auto" style="font-style:italic"><a href="OOPSLA" title="OOPSLA">OOPSLA</a> 2016</cite>. New York 2016, ISBN 978-1-4503-4444-9, <span style="white-space:nowrap">S.<span style="display:inline-block;width:.2em"> </span>838–848</span> (englisch, <a rel="nofollow" class="external text" href="https://raw.githubusercontent.com/namin/unsound/master/doc/unsound-oopsla16.pdf">githubusercontent.com</a> [PDF; <span style="white-space:nowrap">215<span style="display:inline-block;width:.2em"> </span>kB</span>; abgerufen am 31. März 2017]).<span class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rfr_id=info:sid/de.wikipedia.org:Generische+Programmierung+in+Java&rft.atitle=Java+and+Scala%E2%80%99s+Type+Systems+are+Unsound%3A+The+Existential+Crisis+of+Null+Pointers&rft.au=Nada+Amin%2C+Ross+Tate&rft.btitle=OOPSLA+2016&rft.date=2016&rft.genre=book&rft.isbn=9781450344449&rft.pages=838-848&rft.place=New+York" style="display:none"> </span></span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text">Joachim Goll, Cornelia Heinisch: <cite style="font-style:italic">Java als erste Programmiersprache: Grundkurs für Hochschulen</cite>. 8. Auflage. Springer, Wiesbaden 2016, ISBN 978-3-658-12117-4, <span style="white-space:nowrap">S.<span style="display:inline-block;width:.2em"> </span>725</span>.<span class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rfr_id=info:sid/de.wikipedia.org:Generische+Programmierung+in+Java&rft.au=Joachim+Goll%2C+Cornelia+Heinisch&rft.btitle=Java+als+erste+Programmiersprache%3A+Grundkurs+f%C3%BCr+Hochschulen&rft.date=2016&rft.edition=8&rft.genre=book&rft.isbn=9783658121174&rft.pages=725&rft.place=Wiesbaden&rft.pub=Springer" style="display:none"> </span></span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><a href="#cite_ref-3">↑</a></span> <span class="reference-text">Reinhard Schiedermeier: <cite style="font-style:italic">Programmieren mit Java</cite>. 2. Auflage. Pearson Studium, München 2010, ISBN 978-3-86894-031-2, <span style="white-space:nowrap">S.<span style="display:inline-block;width:.2em"> </span>375</span>.<span class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Abook&rfr_id=info:sid/de.wikipedia.org:Generische+Programmierung+in+Java&rft.au=Reinhard+Schiedermeier&rft.btitle=Programmieren+mit+Java&rft.date=2010&rft.edition=2&rft.genre=book&rft.isbn=9783868940312&rft.pages=375&rft.place=M%C3%BCnchen&rft.pub=Pearson+Studium" style="display:none"> </span></span>
</li>
</ol></div><!--htdig_noindex--><div><div class="zim-footer">
Dieser Artikel wurde von <a class="external text" title="Zuletzt bearbeitet am 2025-08-13" href="https://de.wikipedia.org/wiki/?title=Generische_Programmierung_in_Java&oldid=258832035">Wikipedia</a> herausgegeben. Der Text ist unter <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.de">Creative Commons Attribution-Share Alike 4.0</a> verfügbar, sofern nicht anders angegeben. Für die Mediendateien können zusätzliche Bedingungen gelten.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
<script src="./_webp_/webpHandler.js"></script>
</body></html>